import path from 'path';
import fs from 'fs';
import decorator from '../decorator';


let _relativePath, _classPath, _config, _router;
let _method = ['get', 'post', 'all', 'delete'];
let _filters = [];
let _dataType = {
	'html': 'text/html',
	'json': 'application/json',
	'jsonp': 'application/javascript',
	'txt': 'text/plain',
	'pdf': 'application/pdf'
};
let _util = {

	getArgs: function(func) {
		// 先用正则匹配,取得符合参数模式的字符串.
		// 第一个分组是这个: ([^)]*) 非右括号的任意字符
		var args = func.toString().match(/function\s.*?\(([^)]*)\)/)[1];
		// 用逗号来分隔参数(arguments string).
		return args.split(",").map(function(arg) {
			// 去除注释(inline comments)以及空格
			return arg.replace(/\/\*.*\*\//, "").trim();
		}).filter(function(arg) {
			// 确保没有 undefined.
			return arg;
		});
	},
	model: function(config, req, res) {
		var _datas = {};
		this.put = function(key, value) {
			_datas[key] = value;
			return this;
		}
		this.getAll = function() {
			return _datas;
		}
		if(config.dataType) {
			res.set('Content-Type', _dataType[config.dataType]);
		}
		
	}

};

let _Method = {

	/**
	 *
	 **/
	initControll: function() {
		let _this = this;
		let config = _config.servlet;
		function _Map(options) {

			let _conts = options.mapping;
			_conts = _U.type(_conts) === 'string' ? [_conts] : _conts;
			
			for (let i = _conts.length - 1; i >= 0; i--) {
				
			  	try{
				   	let _p = path.join(_classPath, _conts[i]),
						_ds = fs.readdirSync(_p);				
					_ds.forEach(function(obj) {
						let p = path.join(_relativePath, _conts[i], obj);
				   		_U.def(_conts[i]+'/'+obj);
						_this.iControll(options.url, require(p).default);
					});		
				}catch(e){
			   		_U.error(`load controller error (${e})`);
				}
			}
		}
		_U.log('---------------------load controller start!---------------------');
		console.time('load controller consume times');
		for (let i in config) _Map(config[i]);
		console.timeEnd('load controller consume times');
		_U.log('---------------------load controller end!---------------------');
	},
	iControll: function(r, c) {
		let _c = new c();
		if(!c._isController_) return;
		let _this = this;
		let _Server_ = c._Server_;

		async function _Response(_method, req, res, next) {
			let config = _method._config_;
			let model = new _util.model(config, req, res);
			let _return = await _method(req, model);
			if(_U.type(_return) === 'object') _return = JSON.stringify(_return);
			if(!config.dataType) {
				res.render(_return, model.getAll());
			}else if(config.dataType.toLowerCase() === 'jsonp') {
				var _callback = req.query.callback;
				if(_callback) res.send(`${_callback}( ${_return} )`);
				else res.send(_return);
			}else {
				res.send(_return);
			}
		}

		function _Map(_server_) {

			
			let option = _server_,
				config = option.config,
				_r = path.join(r, _Server_.value || '', config.value);
				_c[option.method]._config_ = config;
			_router[config.method](_r, _this.filters, function(req, res, next) {
				_Response(_c[option.method], req, res, next);

			/**	var func = _c[option.method],
					args = _util.getArgs(func);

				args = args.map(function(arg) {
					if(arg === '$req') return req;
					else if(arg === '$res') return res;
					else if(arg === '$next') return next;
					else {
						return req.body[arg] || req.params[arg] || req.query[arg];
					}
				}); **/
			//	func.apply(func, args);
			} );
		}

		for (let i = c._server_.length - 1; i >= 0; i--) _Map(c._server_[i]);
	
	},
	filters: function(req, res, next) {
		console.log('****filter****');
		next();
	},
	initFilter: function() {

		let config = _config.filter;

		function _Map(options) {
			
			try{

				let p = path.join(_relativePath, options.bin);
				options.action = new require(p).default(options.param);

			}catch(e){
		   		_U.error(`load filter error (${e})`);
			}

		/**
			_router.use('', function(req, res, next) {

				_c.doFilter(req, res, next);

			});
		**/
		}

		_U.log('---------------------load controller start!---------------------');
		console.time('load controller consume times');
		for (let i in config) _Map(config[i]);
		console.timeEnd('load controller consume times');
		_U.log('---------------------load controller end!---------------------');
	},
	iFilter: function() {

	}
};

function Router(options) {

	_classPath = options.relPath;
	_relativePath = path.relative(__dirname, _classPath);
	_config = options.config;
	_router = options.router;
//	_Method.initFilter();
	_Method.initControll();
	
}

export default Router;